#include "cybertron/node/BaseApp.hpp"
#include "cybertron/node/AgentClient.hpp"
#include "Node/Common.pb.h"
#include "Node/Agent.pb.h"
#include "cybertron/core/JsonReader.hpp"
// #include "cybertron/core/Log.hpp"
// #include "cybertron/core/UtilPath.hpp"
// #include "cybertron/core/Thread.hpp"
// #include "cybertron/core/UtilConsole.hpp"
#include "cybertron/core/UtilCRT.hpp"
#include "cybertron/network/CybertronSyncConn.hpp"
#include "cybertron/license/License.hpp"
// #include "cybertron/node/StartupArguments.hpp"
// #include "cybertron/core/CoreVersion.hpp"
// #include "cybertron/core/SimOneEnv.hpp"
// #include "cybertron/core/UtilUuidxx.hpp"

CYBERTRON_BEGIN
struct WorkNodeNetInfo{
	WorkNodeNetInfo() {
		isInitNetInfo = false;

	}
	std::string publicIP;
	int publicPort;
	std::string agentId;
	std::string workNodeId;
	Common::EWorkNodeType workType;
	std::string workName;
	bool isNeedStart;
	bool isInitNetInfo;
	
};

struct HostVehiclesBaseConfig {
	std::string hostVehiclesId;
	std::string workNodeId;
	float hotAreaRange;
	int hz;
	float speed;
	float posX;
	float posY;
	float posZ;
	float rotX;
	float rotY;
	float rotZ;
};

struct WorkNodeBaseConfig {
	std::string workNodeId;
	Common::EWorkNodeType workType;
	std::string workName;
	int hz;
	float speed;
	bool joinTimeSync;
	std::map<string,string> taskFlag;
	std::vector<string> dependHotAreaList;
};

typedef std::map<std::string, WorkNodeBaseConfig> WorkNodeBaseConfigMap;
typedef std::map<std::string, HostVehiclesBaseConfig> HostVehiclesBaseConfigMap;
class WorkApp : public BaseApp
{
public:
    WorkApp();
    virtual ~WorkApp();
    virtual bool init(int argc, char* argv[]);
    bool isRunning();
    void stopRunning();
	void setServerListenPort(int listenPort);
    Agent::WorkNodeRegisterRet* getWorkNodeRegisterRetData();
    Common::EWorkNodeType getWorkNodeType();
	std::string getWorkId() { return mWorkId; }
    std::map<std::string, WorkNodeNetInfo*>* getSyncWorkNodeNetInfoMap();
    WorkNodeNetInfo* getWorkNodeNetInfo(const Common::EWorkNodeType& workType);
    WorkNodeNetInfo* getWorkNodeNetInfo(const std::string& workType);

	bool connectWorkServer(std::string workId, CybertronSyncConn& client);

	bool getWorkIdListByType(Common::EWorkNodeType workType, std::vector<std::string>& workIdList);
	std::string getHostVehicleIdByWorkId(std::string worknodeId);
	std::string getWorkIdByHostVehicleId(std::string vehicleId);
	bool isContainWorkNode(Common::EWorkNodeType workNodeType);
	std::vector<std::string>* getWorkNodeDependHotAreaId();
    virtual int beforeRun();

	virtual bool onLoadConfig();
    virtual bool onTaskStartBefore();
	virtual bool onTaskStart();
    virtual bool onTaskStartAfter();
	virtual bool onTaskRunning();
	virtual bool onTaskStop();

    virtual void onWorkNodeStop() {};
	
	bool waitForAllWorkNodeNetInfo();
	bool endTask(Common::ETaskEndReason reason);
	void SendToSimOneInMainVehicle(std::string hostVehicle, uint16_t msg, SocketBasePtr pSender, const google::protobuf::MessageLite& protobufMsg);
public:
	bool getWorkJsonFromWeb(cybertron::json& workRoot);
protected:
	void syncWorkDynamicConfig(int port);
	void setAllWorkNodeOnTaskStart(Master::TaskStartFromCommander* pStartConfig);
	bool setWorkNodeNetInfo(Common::SyncWorkNodeDynamicConfig* pdyConfig);
    void zeroMembers();
    bool setState(const Common::EWorkNodeState &state);
    bool syncWorkNodeState();
	
    int parseArguments(int argc, char* argv[]);
	int parseArguments(string flag, string value);
    void parseMessage(const Message &msg);
    void agentRunThread();
	void stateCheckThread();
	void checkLicenseThread();
	bool isNeedCreateHotArea();
protected:
    std::shared_ptr<cybertron::AgentClient> mpAgentClient;
    std::string mAgentPublicIP;
	int mAgentListenPort;
    bool mbAgentThreadRunning;
	bool mbstateCheckThreadRunning;
    bool mbTaskHaveRun;
    std::string mWorkId;
    std::string mTaskId;
	std::string mAgentId;
    Common::EWorkNodeType mWorkType;
	std::string mWorkName;
	
    std::atomic<Common::EWorkNodeState> mWorkState;

	typedef std::map<std::string, WorkNodeNetInfo*>WorkNodeNetInfoMap;
	WorkNodeNetInfoMap	 mSyncWorkNodeNetInfoMap;
    Agent::WorkNodeRegisterRet mWorkNodeRegisterRetData;
	Agent::TaskStopFromAgent mTaskStopFromeAgent;
	int mServerListenPort;

	WorkNodeBaseConfig mSeflWorkNodeBaseConfig;
	WorkNodeBaseConfigMap mWorkNodeBaseConfigMap;
	HostVehiclesBaseConfigMap mHostVehiclesBaseConfigMap;
	std::string mWebToken;
	std::string mWebIP;
	std::string mWebPort;
	std::string mAgentConnectIp;

	//std::string mWebHost;

	cybertron::json mConfigSceneJsonRoot;
	SimOneLicense mLicense;
	std::atomic<bool> mLicenseState;
};

CYBERTRON_END